/************************************************************
* author: alexander.aivars <alexander.aivars&#64;svt.se>
* $Date:2008-01-18 16:34:37 +0100 (Fri, 18 Jan 2008) $
* $Revision:211 $
* $HeadURL:svn://stoiis03.internt.svt.se/SVTiFLASH/trunk/SVTSE/Source/Classes/se/svt/controls/ScrollBar.as $
* $Id:ScrollBar.as 211 2008-01-18 15:34:37Z alai $
************************************************************/
package se.svt.controls
{
	import flash.display.DisplayObject;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	import se.svt.events.ScrollEvent;

	/**
	* Dispatched when the ScrollBar instance's scrollPosition property changes.
	* @eventType se.svt.events.ScrollEvent.SCROLL
	*/
	[Event(name="scroll", type="se.svt.events.ScrollEvent")]
		
	/**
	* Dispatched when the ScrollBar instance's scrollPosition property starts to change.
	* @eventType se.svt.events.ScrollEvent.SCROLL_START
	*/
	[Event(name="scrollStart", type="se.svt.events.ScrollEvent")]

	/**
	* Dispatched when the ScrollBar instance's scrollPosition property finishes changing.
	* @eventType se.svt.events.ScrollEvent.SCROLL_STOP
	*/
	[Event(name="scrollStop", type="se.svt.events.ScrollEvent")]

	public class ScrollBar extends EventDispatcher
	{
		protected var stage:Stage;

		protected var _displayObject:IScrollBarView; 
		protected var _current:Point;
		protected var _start:Point;
		protected var _range:int;
		protected var _previous:Point;
		protected var _scrolling:Boolean;
		protected var _direction:String;

		public var _bounds:Rectangle;

		/**
		 * Create a scrollbar controler
		 * @param view
		 * 
		 */
		public function ScrollBar(displayObject:IScrollBarView,range:int,direction:String = ScrollBarDirection.HORIZONTAL)
		{
			super();
			this._displayObject = displayObject;
			this._direction = direction;
			this.stage = this.displayObject.stage;
			this.range = range;



			
			//this.bounds = bounds?bounds:new Rectangle();


			this.displayObject.addEventListener(Event.ADDED_TO_STAGE,getStage);

			_displayObject.handle.addEventListener(MouseEvent.MOUSE_DOWN,onPressHandle);
			
		}
		
		protected function set range(val:int):void
		{
			_range = val;
	
			var rect:Rectangle = new Rectangle(_displayObject.handle.x,_displayObject.handle.y,0,0);
			switch (_direction)
			{
				case ScrollBarDirection.VERTICAL:
					rect.height = val;
					rect.width = 0; 
				break;

				default: // ScrollBarDirection.HORIZONTAL:
					rect.height = 0;
					rect.width = val; 
				break;
			}
			
			_bounds = rect;
		}


		protected function getStage(event:Event):void
		{
			stage = displayObject.stage;	
		}
		
		protected function onPressHandle(event:MouseEvent):void
		{

			var dist:Number;
			var delta:Number;
			
			stage.addEventListener(MouseEvent.MOUSE_UP,onReleaseHandle);
			stage.addEventListener(MouseEvent.MOUSE_MOVE,onMoveHandle);
			_scrolling = true;

			_displayObject.handle.startDrag(false,_bounds);

			_start = new Point(_displayObject.handle.x,_displayObject.handle.y);
			_previous = _start;
			_current = _start;			

			switch (_direction)
			{
				case ScrollBarDirection.VERTICAL:
					dist =  _current.y / _range  ;
					delta = (_current.y - _start.y) / _range;
				break;

				default: // ScrollBarDirection.HORIZONTAL:
					dist =  _current.x / _range;
					delta = (_current.x - _start.x) / _range;
				break;

			}

			dispatchEvent(new ScrollEvent(ScrollEvent.SCROLL_START,dist,delta));			
				

//			dispatchEvent(new ScrollEvent(ScrollEvent.SCROLL_START,_current,_current.subtract(_start)));			

		}

		protected function onMoveHandle(event:MouseEvent):void
		{
			var dist:Number;
			var delta:Number;	
					
			_scrolling = true;
			_previous	= _current;
			_current	= new Point(_displayObject.handle.x,_displayObject.handle.y);
		
			if(!_current.equals(_previous)) {
				switch (_direction)
				{
					case ScrollBarDirection.VERTICAL:
						dist =  _current.y / _range  ;
						delta = (_current.y - _start.y) / _range;
					break;

					default: // ScrollBarDirection.HORIZONTAL:
						dist =  _current.x / _range;
						delta = (_current.x - _start.x) / _range;
					break;

				}
				
				dispatchEvent(new ScrollEvent(ScrollEvent.SCROLL,dist,delta));			
			}	

		}
		
		protected function onReleaseHandle(event:MouseEvent):void
		{
			stage.removeEventListener(MouseEvent.MOUSE_UP,onReleaseHandle);
			stage.removeEventListener(MouseEvent.MOUSE_MOVE,onMoveHandle);


			var dist:Number;
			var delta:Number;	

			_displayObject.handle.stopDrag();
			_scrolling = false;
			_previous	= _current;
			_current	= new Point(_displayObject.handle.x,_displayObject.handle.y);

			switch (_direction)
			{
				case ScrollBarDirection.VERTICAL:
					dist =  _current.y / _range  ;
					delta = (_current.y - _start.y) / _range;
				break;

				default: // ScrollBarDirection.HORIZONTAL:
					dist =  _current.x / _range;
					delta = (_current.x - _start.x) / _range;
				break;

			}
				
			dispatchEvent(new ScrollEvent(ScrollEvent.SCROLL_STOP,dist,delta));			
			
		}
		
		/**
		 * Gets the scrollBar display object
		 * @return 
		 */
		public function get displayObject():DisplayObject
		{
			return _displayObject as DisplayObject;	
		}
		
		
		protected function set scroll(point:Point):void
		{
			_displayObject.handle.x = point.x;
			_displayObject.handle.y = point.y;
		}

		protected function get scroll():Point
		{
			return new Point(_displayObject.handle.x,_displayObject.handle.y);
		}
		
		protected function get scrolling():Boolean { return _scrolling; }
		
		
	}
}